import org.apache.iotdb.rpc.IoTDBConnectionException;
import org.apache.iotdb.rpc.StatementExecutionException;
import org.apache.iotdb.rpc.TSStatusCode;
import org.apache.iotdb.session.Session;
import org.apache.iotdb.session.template.MeasurementNode;
import org.apache.iotdb.session.template.Template;
import org.apache.iotdb.session.util.Version;
import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType;
import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
import org.glassfish.jaxb.core.v2.model.core.ID;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

// create STORAGE GROUP root.dvid;
// create SCHEMA template tp_dvid aligned(ptt INT64, app_duration INT64, event_name TEXT);
// create SCHEMA template tp_dvid (ptt INT64, app_duration INT64, event_name TEXT);
// set SCHEMA TEMPLATE tp_dvid to root.dvid;
public class Demo {
    private static Session session;
    private static int eventNameIndex;
    private static final String ROOT_SG1_D1 = "root.sg1.d1";
    private static final String ROOT_DVID = "root.dvid";
    // private static final String LOCAL_HOST = "172.27.255.239";
    private static final String LOCAL_HOST = "127.0.0.1";

    public static void main(String[] args) throws IoTDBConnectionException, IOException {
        session = new Session.Builder()
                .host(LOCAL_HOST)
                .port(6667)
                .username("root")
                .password("root")
                .version(Version.V_0_13)
                .build();
        session.open(false);

        // set session fetchSize
        session.setFetchSize(10000);

        try {
            // setStorageGroup
            session.setStorageGroup("root.dvid");

            // create template
            Template template = new Template("dv_temp", false);
            MeasurementNode mNodeS1 = new MeasurementNode("ptt", TSDataType.INT64, TSEncoding.RLE,
                    CompressionType.SNAPPY);
            MeasurementNode mNodeS2 = new MeasurementNode("app_duration", TSDataType.INT64, TSEncoding.RLE,
                    CompressionType.SNAPPY);
            MeasurementNode mNodeS3 = new MeasurementNode("event_name", TSDataType.TEXT, TSEncoding.PLAIN,
                    CompressionType.SNAPPY);

            template.addToTemplate(mNodeS1);
            template.addToTemplate(mNodeS2);
            template.addToTemplate(mNodeS3);
            session.createSchemaTemplate(template);

            // set template
            session.setSchemaTemplate("dv_temp", "root.dvid");
        } catch (StatementExecutionException e) {
            // e.printStackTrace();
        }
        // return;

        int IDCnt = 1000 * 10;
        int eventCnt = 10;
        long startTime = System.currentTimeMillis();
        System.out.println(startTime);
        try {
            insertRecord(IDCnt, eventCnt);
        } catch (StatementExecutionException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        long endTime = System.currentTimeMillis();
        long costTime = endTime - startTime;
        System.out.println("costTime:" + costTime + "ms");
        System.out.println("tpms:" + (IDCnt * eventCnt) / costTime * 1.0);
    }

    private static void insertRecord(int IDCnt, int eventCnt)
            throws IoTDBConnectionException, StatementExecutionException {
        long baseTime = System.currentTimeMillis();
        for (long eventIndex = 0; eventIndex < eventCnt; eventIndex++) {
            long time = eventIndex * 1000 + baseTime;
            long ptt = eventIndex * 1000 + 1399931004;
            for (int id = 0; id < IDCnt; id++) {
                String deviceId = ROOT_DVID + "." + id;
                List<String> measurements = new ArrayList<>();
                List<TSDataType> types = new ArrayList<>();

                measurements.add("ptt");
                measurements.add("app_duration");
                measurements.add("event_name");

                types.add(TSDataType.INT64);
                types.add(TSDataType.INT64);
                types.add(TSDataType.TEXT);

                // List<String> values = new ArrayList<>();
                List<Object> values = new ArrayList<>();
                values.add(ptt);
                values.add(eventIndex + id);
                values.add(getEventName());

                session.insertRecord(deviceId, time, measurements, types, values);
                // session.insertAlignedRecord(deviceId, time, measurements, values);
            }
        }
        return;
    }

    private static String getEventName() {
        String eventName[] = {
                "ZDEN_AppStart",
                "ZDEN_PageIn",
                "screenName",
                "screenName",
                "ZDEN_DeviceInfo",
                "screenName",
                "screenName",
                "screenName",
                "screenName",
                "ZDEN_UserChange",
                "ZDEN_AppStart",
                "ZDEN_PageIn",
                "screenName",
                "ZDEN_DeviceInfo",
                "screenName",
                "screenName",
                "screenName",
                "screenName",
                "screenName",
                "screenName",
                "ZDEN_UserChange",
                "ZDEN_AppStart",
                "ZDEN_PageIn",
                "ZDEN_DeviceInfo",
                "screenName",
                "screenName",
                "screenName",
                "screenName",
                "screenName",
                "screenName",
                "ZDEN_DeviceInfo",
                "ZDEN_DeviceInfo",
                "ZDEN_DeviceInfo",
                "screenName",
                "screenName",
                "screenName",
                "ZDEN_Onload",
                "ZDEN_NetworkRequest",
                "ZDEN_Click",
                "ZDEN_Typing",
                "ZDEN_Typing",
                "ZDEN_Typing",
                "ZDEN_Typing",
                "ZDEN_NetworkRequest",
                "ZDEN_Typing",
                "ZDEN_NetworkRequest",
                "ZDEN_Typing",
                "ZDEN_Typing",
                "ZDEN_Resize",
                "ZDEN_Typing",
                "ZDEN_Typing",
                "ZDEN_Typing",
                "ZDEN_Typing",
                "ZDEN_NetworkRequest",
                "ZDEN_NetworkRequest",
                "ZDEN_NetworkRequest",
                "ZDEN_NetworkRequest",
                "ZDEN_Onload",
                "ZDEN_NetworkRequest",
                "ZDEN_NetworkRequest",
                "ZDEN_NetworkRequest",
                "ZDEN_Typing",
                "ZDEN_Click",
                "buttonClick_next_signInUserName",
                "screenName",
                "ZDEN_NetworkRequest",
                "ZDEN_PageJumpH5",
                "ZDEN_NetworkRequest",
                "ZDEN_Typing",
                "ZDEN_Typing",
                "ZDEN_Resize",
                "ZDEN_Typing",
                "ZDEN_Typing",
                "ZDEN_Click",
                "buttonClick_signIn_signInPassword",
                "screenName",
                "ZDEN_NetworkRequest",
                "signInFailure",
                "ZDEN_Resize",
                "ZDEN_NetworkRequest",
                "ZDEN_NetworkRequest",
                "ZDEN_NetworkRequest",
                "ZDEN_NetworkRequest",
                "ZDEN_NetworkRequest",
                "ZDEN_NetworkRequest",
                "ZDEN_NetworkRequest",
                "ZDEN_NetworkRequest",
                "ZDEN_NetworkRequest",
                "ZDEN_NetworkRequest",
                "ZDEN_NetworkRequest",
                "ZDEN_PageJumpManual",
                "screenName",
                "ZDEN_GoBack",
                "ZDEN_Resize",
                "ZDEN_NetworkRequest",
                "ZDEN_NetworkRequest",
                "ZDEN_Onload",
                "ZDEN_NetworkRequest",
                "ZDEN_NetworkRequest",
                "ZDEN_NetworkRequest",
                "ZDEN_Typing",
                "ZDEN_Click",
                "ZDEN_NetworkRequest",
                "ZDEN_Typing",
                "ZDEN_Resize",
                "ZDEN_Typing"
        };

        return eventName[eventNameIndex++ % eventName.length];
    }

    private static void insertRecord() throws IoTDBConnectionException, StatementExecutionException {
        String deviceId = ROOT_SG1_D1;
        List<String> measurements = new ArrayList<>();
        List<TSDataType> types = new ArrayList<>();
        measurements.add("s1");
        measurements.add("s2");
        measurements.add("s3");
        types.add(TSDataType.INT64);
        types.add(TSDataType.INT64);
        types.add(TSDataType.INT64);

        for (long time = 1000 * 1000; time < 1000 * 2000; time += 1000) {
            List<Object> values = new ArrayList<>();
            values.add(1L);
            values.add(2L);
            values.add(3L);
            session.insertRecord(deviceId, time, measurements, types, values);
        }
    }
}
